let num: number = 1
let string: string = 'typescript'
let isflag: boolean = false
let arr: number[] = [1, 2, 3]
let arr2: Array<number> = [1, 2, 3]
let arr3: string[] = ['1', '2', '3']
let obj: Object = {}
let u: undefined = undefined
let n: null = null

enum LogLevel {
  info = 'info',
  warning = 'warning',
  error = 'error'
}

let tupleX: [string, number]
tupleX = ['元组', 12]

let notSure: any = 4
notSure = '123'
notSure = [1, 2, 3]

function warnUser(): void {
  console.log('this is a warn info ');
}



function sum1(a: number, b: number): number {
    return a + b
}


interface Point {
    x: number
    y: number
}

function sum2({ x,  y}: Point): number {
    return x + y
}

sum2({ x: 1, y: 2 }) // 3


// 泛型
// 语法 <T>(arg:T):T 其中T为自定义变量
const hello : string = "Hello vue!"
function say1<T>(arg: T): T {
    return arg;
}
console.log(say1(hello)) // Hello vue! 


// 泛型约束
interface Lengthwise {
    length: number;
}

function say2<T extends Lengthwise>(arg: T): T {
	console.log(arg.length)
  return arg;
}
console.log(say2(1))  // Argument of type '1' is not assignable to parameter of type 'Lengthwise'.
console.log(say2({value: 'hello vue!', length: 10})) // { value: 'hello vue!', length: 10 } 
console.log(say2({ pp: 1, length: 10 })) // { pp: 1, length: 10 } 



// 交叉类型(Intersection Types)
interface foo {
    x: number
}
interface bar {
    b: number
}
type intersection = foo & bar // 集合操作
const result: intersection = {
    x: 10,
    b: 20
}
const result1: intersection = {
    x: 10
}  // error



// 联合类型(Union Types)，表示一个值可以是几种类型之一
type arg = string | number | boolean
const foo = (arg: arg):any =>{ 
    console.log(arg)
}
foo(1)
foo('2')
foo(true)



// 函数重载（Function Overloading）

// 例我们有一个add函数，它可以接收string类型的参数进行拼接，也可以接收number类型的参数进行相加
function add (arg1: string, arg2: string): string
function add (arg1: number, arg2: number): number

// 实现
function add <T,U>(arg1: T, arg2: U) {
  // 在实现上我们要注意严格判断两个参数的类型是否相等，而不能简单的写一个 arg1 + arg2
  if (typeof arg1 === 'string' && typeof arg2 === 'string') {
    return arg1 + arg2
  } else if (typeof arg1 === 'number' && typeof arg2 === 'number') {
    return arg1 + arg2
  }
}

add(1, 2) // 3
add('1', '2') //'12'

